<html>
    <head>
        <title>如何配置生成动态代理</title>
    </head>
    <body>
        <script>
             /*
                        五、配置  Configuration
                        

                                    1、AbpRemoteServiceOptions选项类

                                                AbpRemoteServiceOptions 默认情况下从 appsetting.json 自动设置。

                                                或者，你可以在模块的 ConfigureServices 方法中配置它以设置或覆盖它。

                                                eg:
                                                        public override void ConfigureServices(ServiceConfigurationContext context)
                                                        {
                                                            context.Services.Configure<AbpRemoteServiceOptions>(options =>
                                                            {
                                                                options.RemoteServices.Default =
                                                                    new RemoteServiceConfiguration("http://localhost:53929/"); // 配置API端点根路径
                                                            });
                                                        }


                                        
                                    2、多个远程服务端点（端口）  

                                                上面的示例配置了"默认"远程服务端点。你可能对不同的服务有不同端点（就像在微服务方法中，每个微服务都有不同的端点）。

                                                在这种情况，你可以将其他端点添加到配置中：

                                                          {
                                                            "RemoteServices": {
                                                                "Default": {
                                                                    "BaseUrl": "http://localhost:53929/"
                                                                },
                                                                "BookStore": {
                                                                    "BaseUrl": "http://localhost:48392/"
                                                                } 
                                                            } 
                                                        }   
                                                            
                                                AddHttpClientProxies 方法可以获取远程服务名称的附加参数：

                                                eg：
                                                    context.Services.AddHttpClientProxies(
                                                        typeof(BookStoreApplicationContractsModule).Assembly,
                                                        remoteServiceConfigurationName: "BookStore"   // 指定服务对应Configuration的节点名称
                                                    );

                                                    remoteServiceConfigurationName参数匹配通过AbpRemoteServiceOptions配置的服务端点。

                                                    如果BookStore端点未定义，则它回退到Default端点。


                                                
                                    3、远程服务配置提供程序  RemoteServiceConfigurationProvider 

                                                    在某些情况下，你可能需要获取特定远程服务的远程服务配置。

                                                    为此，你可以使用  IRemoteServiceConfigurationProvider 接口。

                                                    eg:  获取“BookStore”远程服务的远程服务配置

                                                        public class MyService : ITransientDependency
                                                        {
                                                            private readonly IRemoteServiceConfigurationProvider _remoteServiceConfigurationProvider;

                                                            public MyService(IRemoteServiceConfigurationProvider remoteServiceConfigurationProvider)
                                                            {
                                                                _remoteServiceConfigurationProvider = remoteServiceConfigurationProvider; // 注入远程服务配置提供程序服务
                                                            }

                                                            public async Task GetRemoteServiceConfiguration()
                                                            {
                                                                var configuration = await _remoteServiceConfigurationProvider.GetConfigurationOrDefaultAsync("BookStore"); // 获取远程服务配置
                                                                Console.WriteLine(configuration.BaseUrl);
                                                            }
                                                        }

                                                
                                    4、  asDefaultServices 选项 (作为默认服务实现)

                                                    当您为IBookAppService创建服务代理时，您可以直接注入IBookAppService来使用代理客户端（如使用部分所示）。

                                                    可以将asDefaultServices: false传递给AddHttpClientProxies方法来禁用此功能。

                                                    eg:

                                                         context.Services.AddHttpClientProxies(
                                                                typeof(BookStoreApplicationContractsModule).Assembly,
                                                                asDefaultServices: false
                                                        );

                                                    仅当您的"客户端应用程序" 已经有服务的实现并且您不想被客户端代理覆盖/替换其他实现时，才可能需要使用asDefaultServices: false。

                                                    
                                                  备注： 如果禁用asDefaultServices，则只能使用IHttpClientProxy<T>接口来使用客户端代理。



                                    5、失败重试逻辑 和 Polly集成
                                    
                                                    如果想为客户单端代理在请求失败时添加重试逻辑，可以在模块类的 PreConfigureServices 方法中配置  AbpHttpClientBuilderOptions

                                                    eg: 使用Polly库在失败时重试3次

                                                        public override void PreConfigureServices(ServiceConfigurationContext context)
                                                        {
                                                            PreConfigure<AbpHttpClientBuilderOptions>(options =>
                                                            {
                                                                options.ProxyClientBuildActions.Add((remoteServiceName, clientBuilder) =>
                                                                {
                                                                    clientBuilder.AddTransientHttpErrorPolicy(policyBuilder =>
                                                                        policyBuilder.WaitAndRetryAsync(
                                                                            3,
                                                                            i => TimeSpan.FromSeconds(Math.Pow(2, i))
                                                                        )
                                                                    );
                                                                });
                                                            });
                                                        }


                                                    此示例使用 "Microsoft. Exents.Http.Polly" 包。
                                                    
                                                    您还需要导入Polly命名空间（using Polly;）才能使用WaitAndRetryAsync方法。
                    */
        </script>
    </body>
</html>